home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Programming / LEDA / source / src / prio / _p_heap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  11.3 KB  |  443 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  _p_heap.c
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15. #include <LEDA/impl/p_heap.h>
  16.  
  17.  
  18. static p_heap const *class_ptr;
  19.  
  20. // ============== comparison_link Macros (s.n.) ================================
  21.  
  22. #define comparison_link(with_el,new_el)\
  23.   if (cmp(with_el->key,new_el->key)<0)\
  24.     { with_el->r_child=new_el->r_child;\
  25.       if (with_el->r_child!=nil)\
  26.               with_el->r_child->parent=with_el;\
  27.       new_el->r_child=with_el->l_child;\
  28.       if (new_el->r_child!=nil)\
  29.               new_el->r_child->parent=new_el;\
  30.       new_el->parent=with_el;  \
  31.       with_el->l_child=new_el; }\
  32.   else\
  33.     { with_el->r_child=new_el->l_child;\
  34.       if (with_el->r_child!=nil)\
  35.               with_el->r_child->parent=with_el;\
  36.       new_el->parent=with_el->parent;\
  37.       if (new_el->parent!=nil)\
  38.               new_el->parent->r_child=new_el; \
  39.       new_el->l_child=with_el;\
  40.       with_el->parent=new_el;\
  41.       with_el = new_el; }
  42.  
  43. #define int_comparison_link(with_el,new_el)\
  44.   if (with_el->key < new_el->key)\
  45.     { with_el->r_child=new_el->r_child;\
  46.       if (with_el->r_child!=nil)\
  47.               with_el->r_child->parent=with_el;\
  48.       new_el->r_child=with_el->l_child;\
  49.       if (new_el->r_child!=nil)\
  50.               new_el->r_child->parent=new_el;\
  51.       new_el->parent=with_el;  \
  52.       with_el->l_child=new_el; }\
  53.   else\
  54.     { with_el->r_child=new_el->l_child;\
  55.       if (with_el->r_child!=nil)\
  56.               with_el->r_child->parent=with_el;\
  57.       new_el->parent=with_el->parent;\
  58.       if (new_el->parent!=nil)\
  59.               new_el->parent->r_child=new_el; \
  60.       new_el->l_child=with_el;\
  61.       with_el->parent=new_el;\
  62.       with_el = new_el; }
  63.  
  64.  
  65.  
  66. //====== construct (p_heap&) ===========================================
  67.  
  68. p_heap::p_heap(const p_heap& with)
  69. {
  70.     item_count =0;
  71.     if((this!=&with)&&(with.item_count>0)){
  72.         class_ptr=&with;
  73.         copy_sub_tree(head,with.head);
  74.         class_ptr=this;
  75.     }
  76. }
  77.  
  78. //====== operator = =====================================================
  79.  
  80. p_heap& p_heap::operator=(const p_heap& with)
  81. {
  82.       if(this!=&with){
  83.          if((with.item_count>0)&&(item_count>0))
  84.                 clear();
  85.         class_ptr=&with;
  86.         copy_sub_tree(head,with.head);
  87.         class_ptr=this;
  88.                 
  89.         }
  90.         return(*this);
  91. }
  92.  
  93. //=========== copy_sub_tree =============================================
  94.  
  95. void  p_heap::copy_sub_tree(ph_item* whereto,ph_item* from) 
  96. {
  97.    if (item_count==0)   // target tree is empty 
  98.    {
  99.         
  100.          head =new ph_item(from->key,from->inf);
  101.          class_ptr->copy_key(head->key);
  102.          class_ptr->copy_inf(head->inf);
  103.          item_count++;
  104.         
  105.          do_copy(head,from->l_child,true);
  106.    }
  107.  
  108.    else
  109.         
  110.                 if ((cmp(whereto->key,from->key)<=0)  // precondition:
  111.                         &&(whereto->l_child==nil))    // subelement <= parent
  112.                 
  113.                         do_copy(whereto,from,true);
  114.                         // true: that is left child from whereto        
  115. }
  116.  
  117.  
  118.  
  119. //====== do_copy ======================================================
  120.  
  121. void p_heap::do_copy(ph_item* father,ph_item* from,bool direction)
  122. {
  123. // direction : false=right true=left
  124.  
  125.         
  126.         ph_item* hilf=new_ph_item(from->key,from->inf);
  127.         
  128.         hilf->parent=father;
  129.         if (direction)
  130.                 father->l_child=hilf;
  131.         else
  132.                 father->r_child=hilf;
  133.  
  134.         if (from->l_child!=nil)
  135.                 do_copy(hilf,from->l_child,true);
  136.                 
  137.         if (from->r_child!=nil)
  138.                 do_copy(hilf,from->r_child,false);
  139. }
  140.  
  141. //===== new_ph_item =====================================================
  142.  
  143. ph_item* p_heap::new_ph_item(GenPtr key,GenPtr inf)
  144. {
  145.         ph_item* help=new ph_item(key,inf);
  146.  
  147.         copy_key(help->key);
  148.         copy_inf(help->inf);
  149.         help->parent=nil;
  150.         item_count++;
  151.  
  152.         return help;
  153. }
  154.  
  155.         
  156.                 
  157. // ========== clear ====================================================
  158.  
  159. void p_heap::clear()
  160. {
  161.   if (item_count>0)
  162.         clear_sub_tree(head);
  163.         
  164. }
  165.  
  166. // ======= clear_sub_tree ===============================================
  167.  
  168. void p_heap::clear_sub_tree(ph_item* sub)
  169. {
  170.         
  171.         if (sub->l_child!=nil)
  172.                 clear_sub_tree(sub->l_child);
  173.         if (sub->r_child!=nil)
  174.                 clear_sub_tree(sub->r_child);
  175.         if (sub->parent!=nil)
  176.                 if(sub->parent->l_child==sub)
  177.                         sub->parent->l_child=nil;
  178.                 else
  179.                         sub->parent->r_child=nil;
  180.  
  181.         clear_key(sub->key);
  182.         clear_inf(sub->inf);
  183.         delete(sub);
  184.         item_count--;
  185. }
  186.                 
  187.  
  188.  
  189. //======= insert =======================================================
  190.  
  191. ph_item* p_heap::insert(GenPtr key,GenPtr inf)
  192. {       
  193.         ph_item* help;
  194.  
  195.         help = new ph_item(key,inf);
  196.         copy_key(help->key);
  197.         copy_inf(help->inf);
  198.  
  199.         if (item_count==0)      // very first element
  200.           { item_count++;
  201.             head=help;
  202.             return help;
  203.            }
  204.         else                    // just another element
  205.           { item_count++;
  206.             comparison_link(head,help);
  207.             return help;
  208.            }
  209.  
  210.         
  211. }
  212.  
  213.  
  214. // ====== decrease_key ==================================================
  215.  
  216. void p_heap::decrease_key(ph_item* which,GenPtr key)
  217. {
  218.    register ph_item* help2=nil;
  219.    register ph_item* which_parent = which->parent;
  220.  
  221.    if (int_type())
  222.      if (key <= which->key)  // smaller or equal to the old element
  223.       { 
  224.         which->key=key;
  225.    
  226.         if (which!=head)         // which is not already minimum
  227.         { if (which->r_child!=nil)
  228.           { help2=which->r_child;
  229.             help2->parent=which_parent;
  230.             which->r_child=nil;
  231.            }
  232.    
  233.           if (which_parent->l_child==which)
  234.              which_parent->l_child=help2;
  235.           else                    
  236.              which_parent->r_child=help2;
  237.    
  238.           which->parent=nil;
  239.           int_comparison_link(head,which);
  240.          }
  241.       }
  242.      else /* error */;
  243.    else
  244.      if (cmp(key,which->key)<=0)  // smaller or equal to the old element
  245.       { 
  246.         clear_key(which->key);
  247.         which->key=key;
  248.         copy_key(which->key);
  249.    
  250.         if (which!=head)         // which is not already minimum
  251.         { if (which->r_child!=nil)
  252.           { help2=which->r_child;
  253.             help2->parent=which_parent;
  254.             which->r_child=nil;
  255.            }
  256.    
  257.           if (which_parent->l_child==which)
  258.              which_parent->l_child=help2;
  259.           else                    
  260.              which_parent->r_child=help2;
  261.    
  262.           which->parent=nil;
  263.           comparison_link(head,which);
  264.          }
  265.       }
  266.      else /* error */;
  267. }                       
  268.                 
  269.  
  270. //========= delete_min_multipass ()  (multipass algorithm) =============
  271.  
  272. void p_heap::delete_min_multipass()
  273. {
  274.  if (item_count==1)     // only one element in structure
  275.    {
  276.         clear_key(head->key);
  277.         clear_inf(head->inf);
  278.         delete head;
  279.         item_count=0;
  280.    }
  281.    else
  282.    {
  283.         head=head->l_child;
  284.         clear_key(head->parent->key);
  285.         clear_inf(head->parent->inf);
  286.         delete head->parent;    // delete min
  287.         head->parent=nil;
  288.         item_count--;
  289.         
  290.       if (head->r_child!=nil)   // there are two ore more consecutive elements
  291.         head=multipass(head);
  292.     
  293.   }// end else
  294.  
  295. }
  296.  
  297. //======== delete_min_twopass, (twopass algorithm) ============================
  298.  
  299. void p_heap::delete_min_twopass()
  300. {
  301.         
  302.    if (item_count==1)   // only one element in structure
  303.    {
  304.         clear_key(head->key);
  305.         clear_inf(head->inf);
  306.         delete head;
  307.         item_count=0;
  308.    }
  309.    else
  310.    {
  311.         head=head->l_child;
  312.         clear_key(head->parent->key);
  313.         clear_inf(head->parent->inf);
  314.         delete head->parent;    // delete min
  315.         head->parent=nil;
  316.         item_count--;
  317.         
  318.       if (head->r_child!=nil)   // there are two ore more consecutive elements
  319.       
  320.         head=twopass(head);
  321.         
  322.  
  323.       } // end else
  324. }
  325.  
  326.  
  327.  
  328. // ============== twopass ================================================              
  329.         
  330. ph_item*  p_heap::twopass(ph_item* head)
  331. {
  332.  //pass 1 : left to right comparison link (successive pairs of root nodes)
  333.  
  334.   register ph_item* help1,*help2;
  335.  
  336.   help1=head;
  337.   help2=head->r_child;
  338.   
  339.   if (int_type())
  340.         while (help2!=nil)               // there are 2 ore more elements left
  341.         { head=help1->r_child->r_child;   // use of head as a helper
  342.           int_comparison_link(help1,help2);
  343.                 
  344.           if (head!=nil)       // first case comp _link
  345.              if (head->r_child!=nil)
  346.                { // second case
  347.                  // now we have to more nodes to test
  348.                  help2=head->r_child;
  349.                  help1=head;
  350.                 }
  351.              else
  352.                help2=nil;
  353.            else
  354.              { head=help1;     // last element in list
  355.                help2=nil;
  356.               }
  357.           }
  358.    else
  359.         while (help2!=nil)
  360.         { head=help1->r_child->r_child;
  361.           comparison_link(help1,help2);
  362.                 
  363.           if (head!=nil)
  364.              if (head->r_child!=nil)
  365.                { help2=head->r_child;
  366.                  help1=head;
  367.                 }
  368.              else
  369.                help2=nil;
  370.            else
  371.              { head=help1;
  372.                help2=nil;
  373.               }
  374.          }
  375.  
  376.   //pass 2 : right to left comparison link (allways the two rightmost nodes)
  377.  
  378.         help1=head->parent;
  379.         help2=head;
  380.  
  381.    if (int_type())
  382.         while (help1!=nil)
  383.         { int_comparison_link(help1,help2);
  384.           head=help1;
  385.           help2=help1;
  386.           help1=help1->parent;
  387.          }
  388.     else
  389.         while (help1!=nil)
  390.         { comparison_link(help1,help2);
  391.           head=help1;
  392.           help2=help1;
  393.           help1=help1->parent;
  394.          }
  395.         
  396.  // head points now again to the very first element
  397.  
  398.  return(head);
  399.  
  400. }
  401.  
  402. // ================ multipass ==========================================
  403.  
  404. ph_item* p_heap::multipass(ph_item* head)
  405. {
  406.           // now pass 1 (multi times) : left to right comparison link (successive pairs of root nodes)
  407.        ph_item* save=head;      
  408.        ph_item* help1,*help2;
  409.  
  410.        while(head->r_child!=nil)
  411.        { save=head;
  412.          help1=head;
  413.          help2=head->r_child;
  414.         
  415.          while (help2!=nil)      // there are 2 ore more elements left
  416.          { save=help1->r_child->r_child; // use of save as a helper
  417.            comparison_link(help1,help2);
  418.                 
  419.            if (save!=nil)       // first case comp _link
  420.              if (save->r_child!=nil)
  421.                 { // second case
  422.                   // now we have to more nodes to test
  423.                   help2=save->r_child;
  424.                   help1=save;
  425.                  }
  426.               else
  427.                  help2=nil;
  428.            else
  429.               { save=help1;     // last element in list
  430.                 help2=nil;
  431.                }
  432.          } // end while (help2!=nil)
  433.  
  434.  
  435.         if (head->parent!=nil)      // may be first element is child (comp link)
  436.                 head=head->parent;
  437.  
  438.     } // end while (repeat pass 1)
  439.  
  440.   return(head);
  441. }
  442.